home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / DirectPlay / SimplePeer / readme.txt < prev    next >
Text File  |  2001-10-10  |  11KB  |  179 lines

  1. //-----------------------------------------------------------------------------
  2. // 
  3. // Sample Name: SimplePeer Sample
  4. // 
  5. // Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
  6. // 
  7. //-----------------------------------------------------------------------------
  8.  
  9.  
  10. Description
  11. ===========
  12.   SimplePeer illustrates how to network other players using DirectPlay.  
  13.   After joining or creating a session, a simple game 
  14.   begins immediately.  Other players may join the game in progress at any time.  
  15.   
  16.   The game itself is very simple, passing a single DirectPlay message to all 
  17.   connected players when the "Wave To other players" button is pressed.
  18.  
  19. Path
  20. ====
  21.   Source: DXSDK\Samples\Multimedia\DirectPlay\SimplePeer
  22.  
  23.   Executable: DXSDK\Samples\Multimedia\DirectPlay\Bin
  24.  
  25. User's Guide
  26. ============
  27.   Enter the player's name, and choose a connection type.  You can either choose 
  28.   "Wait for Lobby Connection" to wait for a lobby connection or choose a 
  29.   service provider.  Use the Multiplayer Games dialog to either search for an 
  30.   active game to join, or to start a new game.  After game has been joined or 
  31.   created, the game begins immediately.  Other players may join the game at 
  32.   any time.  If host migration is on, then the host player may also leave 
  33.   at anytime since DirectPlay will automatically migrate the host player.
  34.  
  35. Programming Notes
  36. =================
  37.   This sample was intended to be very simple, showing the basics of using 
  38.   the DirectPlay API.  Here's a quick run through the various steps 
  39.   of SimplePeer:
  40.   
  41.   * Initialize DirectPlay. See InitDirectPlay()
  42.         1. Init COM with CoInitialize()
  43.         2. Create a IDirectPlay8Peer with CoCreateInstance()
  44.         3. Create a IDirectPlay8LobbiedApplication with CoCreateInstance()
  45.         4. Call IDirectPlay8Peer::Initialize to tell the interface about our 
  46.                 message handler
  47.         5. Call IDirectPlay8LobbiedApplication::Initialize to tell the interface 
  48.                 about our message handler
  49.         6. Check if IDirectPlay8LobbiedApplication::Initialize returned a non-NULL 
  50.                 lobby client connection handle. If it did, then we know we were
  51.                 launched by a lobby client, so it may (but not necessarily) also 
  52.                 have sent us connection settings we can use to either host or join 
  53.                 a game.
  54.         
  55.   * Either host or connect to a DirectPlay game.  See WinMain().
  56.         If we were launched from a lobby client, then we may have connection 
  57.         settings that we can use either host or join a game.  If not, then we'll 
  58.         need to prompt the user to determine how to connect. 
  59.  
  60.     - Host/connect using the connection settings obtained from lobby client.  See 
  61.         CNetConnectWizard::ConnectUsingLobbySettings().
  62.           
  63.         1. Call IDirectPlay8LobbiedApplication::GetConnectionSettings() to get the
  64.                 connection settings from a lobby client.  Note: the connection 
  65.                 settings are also present in the DPL_MSGID_CONNECT message, but if 
  66.                 we use those we would need to make a deep copy of the data since 
  67.                 we don't own pConnectMsg->pdplConnectionSettings.
  68.         2. Check dwFlags for DPLCONNECTSETTINGS_HOST.  This will tell us if we are 
  69.                 hosting or not.
  70.         3. Call IDirectPlay8Peer::SetPeerInfo so other players know our player name.  
  71.                 This isn't necessary, but SetPeerInfo is an easy way to post data 
  72.                 such as the player name so that all of the other clients can access it.
  73.         4. If hosting call IDirectPlay8Peer::Host(), otherwise call 
  74.                 IDirectPlay8Peer::Connect().                    
  75.         5. Cleanup DPL_CONNECTION_SETTINGS.  
  76.         
  77.     - Host/connect by prompting user for connect settings.  See 
  78.         CNetConnectWizard::DoConnectWizard():
  79.         
  80.         This sample calls upon the helper class CNetConnectWizard for this task.
  81.         It uses dialog boxes to query the user what to do, however most games will 
  82.         want to use a fanicer graphics layer such as Direct3D.  Here's what 
  83.         CNetConnectWizard does after calling CNetConnectWizard::DoConnectWizard():
  84.         
  85.         1. CNetConnectWizard enumerates and displays DirectPlay's service providers with
  86.                 IDirectPlay8Peer::EnumServiceProviders. 
  87.                 See CNetConnectWizard::ConnectionsDlgFillListBox()
  88.         2. When a service provider has been chosen via the UI...
  89.                 See CNetConnectWizard::ConnectionsDlgOnOK().         
  90.             - If the user chooses "Wait for Lobby Connection", then it calls 
  91.                 IDirectPlay8LobbiedApplication::SetAppAvailable. This tells the 
  92.                 lobby client that our app is available for connection, so it 
  93.                 doesn't need to launch a new instance of the application.  Then 
  94.                 pops a dialog box that has timer.  The timer checks to see if 
  95.                 m_hLobbyConnectionEvent is signaled (it becomes signaled when a 
  96.                 DPL_MSGID_CONNECT is received).  When it is, then we can call 
  97.                 ConnectUsingLobbySettings().                
  98.             - If the user chooses a SP, it creates a DirectPlay host and device 
  99.                 addresses calling CoCreateInstance.  Then it calls 
  100.                 IDirectPlay8Address::SetSP to pass SP's guid into the two 
  101.                 IDirectPlay8Address's.                 
  102.         3. Call IDirectPlay8Peer::EnumHosts to enum all the games in progress on that SP.            
  103.                 See CNetConnectWizard::SessionsDlgEnumHosts().                
  104.                 We pass in a device address to specify which device to use,
  105.                 and a host address to specify the address of the host.  For TCP/IP, 
  106.                 the host address may contain just the SP to search the local subnet, 
  107.                 or it may have the SP and a have an IP address to search.  If too 
  108.                 little information is supplied and the flag DPNENUMHOSTS_OKTOQUERYFORADDRESSING 
  109.                 is passed then DirectPlay will popup a dialog box to prompt the 
  110.                 user for any extra  needed information.  More complex games would 
  111.                 probably want to not pass this flag, and supply the needed 
  112.                 information so as to avoid unnecessary dialog boxes.                
  113.         4. Process DPN_MSGID_ENUM_HOSTS_RESPONSE messages that come in on the callback.
  114.                 Upon receiving these messages, put them in a data structure.  You 
  115.                 will need to deep copy the DPN_APPLICATION_DESC, and the pAddressSender.  
  116.                 Also be careful to not add duplicates to the list.  You will need 
  117.                 to manage this structure yourself including expiring old enumerations.  
  118.                 See CNetConnectWizard::SessionsDlgNoteEnumResponse() and 
  119.                 CNetConnectWizard::SessionsDlgExpireOldHostEnums().
  120.         5. The wizard displays the list of current sessions (built with step #4) 
  121.                 and allows the user to either choose a game from the list or 
  122.                 create a new one.          
  123.            - If joining a game from the list, it calls IDirectPlay8Peer::SetPeerInfo()
  124.                 to set the player's name, and then calls IDirectPlay8Peer::Connect()
  125.                 passing in the DPN_APPLICATION_DESC, as well as pAddressSender 
  126.                 from the selected game. This will async complete, so wait for 
  127.                 DPN_MSGID_CONNECT_COMPLETE, and read the connect result from msg.
  128.                 See CNetConnectWizard::SessionsDlgJoinGame(), and 
  129.                 CNetConnectWizard::SessionsDlgProc()'s WM_TIMER.
  130.            - If creating a new game, it calls IDirectPlay8Peer::SetPeerInfo()
  131.                 to set the player's name, and then calls IDirectPlay8Peer::Host()
  132.                 passing in a DPN_APPLICATION_DESC filled with various info such
  133.                 as the game name, max players, and the app guid. It also passes in
  134.                 the IDirectPlay8Address that describes which SP to use.
  135.                 See CNetConnectWizard::SessionsDlgCreateGame().
  136.                 
  137.         After either prompting the user with dialog boxes or connecting using 
  138.         settings from a lobby connection, the IDirectPlay8Peer interface will 
  139.         be connected to a DirectPlay session by either hosting a new one or join 
  140.         an existing one. 
  141.                 
  142.   * Handle DirectPlay system messages.  See DirectPlayMessageHandler()
  143.         - Upon DPN_MSGID_CREATE_PLAYER it calls IDirectPlay8Peer::GetPeerInfo
  144.                 to retrieve the player's name.  It then creates a app specific
  145.                 structure for the player, APP_PLAYER_INFO.  It passes the 
  146.                 pointer to this structure to DirectPlay in the pvPlayerContext 
  147.                 field.  This prompts DirectPlay to return that pointer whenever 
  148.                 a message from or about that player is received, so instead of 
  149.                 traversing a data structure to find the player's structure the 
  150.                 pvPlayerContext will be pointing directly to the correct 
  151.                 structure.  Note that since player can be deleted at any time, 
  152.                 we need to use ref counting to make sure this player context struct 
  153.                 isn't deleted while we are still using it.  
  154.         - Upon DPN_MSGID_DELETE_PLAYER it gets the player's structure from 
  155.                 pDeletePlayerMsg->pvPlayerContext and then decrements the
  156.                 ref count for the structure.   If the struct's ref count is zero,
  157.                 the struct is deleted.  
  158.         - Upon DPN_MSGID_CONNECTION_TERMINATED it shuts down the dialog.
  159.         - Upon DPN_MSGID_RECEIVE it casts pReceiveMsg->pReceiveData into 
  160.                 a generic app defined structure that helps it figure out 
  161.                 what structure is really contained in pReceiveMsg->pReceiveData.
  162.                 For this simple example, if the type is GAME_MSGID_WAVE it 
  163.                 just executes an simple action.
  164.                 
  165.   * Send a DirectPlay packet. See WaveToAllPlayers().
  166.         - If the user presses, "Wave to other players!" button then it 
  167.                 calls IDirectPlay8Peer::SendTo() with DPNID_ALL_PLAYERS_GROUP
  168.                 and a data message that is simply a DWORD containing GAME_MSGID_WAVE.                
  169.                 
  170.   * Clean up.  See bottom of WinMain()
  171.         1. Delete the connection wizard class.
  172.         2. Call IDirectPlay8LobbiedApplication::Close()
  173.         3. Release the IDirectPlay8LobbiedApplication
  174.         4. Call IDirectPlay8Peer::Close()
  175.         5. Release the IDirectPlay8Peer
  176.         1. Free any app-specific resources
  177.         6. Call CoUninitialize().
  178.         
  179.